昨天終於解釋完Polymorphism,今天接著來聊聊為什麼要用virtual function虛擬函數。
先來複習一下昨天的code:
#include <iostream>
using namespace std;
class Family{
protected:
string Name;
public:
void setname(string name){
Name = name;
}
string getname(){
return "Family:" + Name;
}
};
class Mom:public Family{
public:
string getname(){
return "Mom's name is " + Name;
}
};
class Dad:public Family{
public:
string getname(){
return "Dad's name is "+ Name;
}
};
class Son:public Mom{
public:
string getname(){
return "Son's name is " + Name;
}
};
int main()
{
string x, y, z;
Family f;
Mom m;
Dad d;
Son s;
Family *f1 = &m;
Family *f2 = &d;
Family *f3 = &s;
cout <<"Type mom's name: ";
cin >> x;
f1 -> setname(x);
cout <<"Type dad's name: ";
cin >> y;
f2 -> setname(y);
cout <<"Type son's name: ";
cin >> z;
f3 -> setname(z);
cout << m.getname() << endl;
cout << d.getname() << endl;
cout << s.getname() << endl;
return 0;
}
讚,接著可以注意到,為什麼在getname()時都還要用m
,而不是直接用已經裝好m記憶體地址的f1
?
那這樣大費周章的放指標f1好像也沒什麼意義,直接用m就好了嘛。
那我們把cout << m.getname() << endl;
改成cout << f1 -> getname() << endl;
看看好了。
假設我們輸入媽媽的名字是"Rose"。
預期輸出:Mom's name: Rose
實際輸出:Family: Rose
哪尼怎麼會這樣~~
因為因為, f1指向的是Family class:Family f1* = &m;
所以為了讓程式知道我們指的是哪個,可以在base class加上virtual:
class Family{
protected:
string Name;
public:
void setname(string name){
Name = name;
}
virtual string getname(){
return "Family:" + Name;
}
};
現在再來試一次,如下:cout << f1 -> getname() << endl;
輸出: Mom's name: Rose
就解決問題了~
Reference: cplusplus.com, The Cherno, Practical C++ Programming, w3school, wikipedia, thenewboston,